﻿using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CoTime.Model;

namespace CoTime.View.UserControls
{
    public partial class UCCanvas : Canvas
    {
        #region [ Constructor ]

        public UCCanvas()
        {
            InitializeComponent();
        }

        public UCCanvas(Int32 id): this()
        {
            this.Name = Consts.Task + id;

            if (this.Tag == null)
            {
                this.Tag = new Task(id);
            }
        }

        #endregion

        #region [ Icons Operation / UI Api]

        public void BindTask(Task task)
        {
            if (task == null)
                return;
            this.Tag = task;

            this.First<UCTextBox>().Text = task.Title;

            if (task.Done)
            {
                Done(updateTask:false);
            }
            else
            {
                UnDone(updateTask: false);
            }

            UIElementCollection els = this.First<Grid>().Children;
            els.Clear();

            foreach (Act act in task.Acts)
            {
                switch (act.ActType)
                {
                    case ActType.AddEstiPomo:
                        AddEsti(updateTask: false);
                        break;
                    case ActType.AddPomo:
                        AddPomo(updateTask: false);
                        break;
                    case ActType.AddAbanPomo:
                        AddAban(updateTask: false);
                        break;
                    case ActType.AddInteInte:
                        AddInte(updateTask: false);
                        break;
                    case ActType.AddExteInte:
                        AddExte(updateTask: false);
                        break;
                    case ActType.DelEstiPomo:
                        DelEsti(updateTask: false);
                        break;
                    case ActType.DelPomo:
                        DelPomo(updateTask: false);
                        break;
                    case ActType.DelAbanPomo:
                        DelAban(updateTask: false);
                        break;
                    case ActType.DelInteInte:
                        DelInte(updateTask: false);
                        break;
                    case ActType.DelExteInte:
                        DelExte(updateTask: false);
                        break;
                }
            }
        }
        public void BindTask(Object task)
        {
            if (task is Task)
            {
                BindTask(task as Task);
            }
            else
            {
                throw new ArgumentNullException("when BindTask(Object task)");
            }
        }

        public void AddEsti(Boolean updateTask = true)
        {
            this.AddIcon("esti", this.CalculateColumn("esti"));
            if (updateTask)
            { 
                (this.Tag as Task).AddAct(ActType.AddEstiPomo, DateTime.Now);
            }
        }
        public void AddPomo(Boolean updateTask = true)
        {
            this.AddIcon("pomo", this.CalculateColumn("pomo"));
            if (updateTask)
            { 
                (this.Tag as Task).AddAct(ActType.AddPomo, DateTime.Now);
            }
        }
        public void AddAban(Boolean updateTask = true)
        {
            this.AddIcon("pomoaban", this.CalculateColumn("pomoaban"));
            if (updateTask)
            { 
                (this.Tag as Task).AddAct(ActType.AddAbanPomo, DateTime.Now);
            }
        }
        public void AddInte(Boolean updateTask = true)
        {
            this.AddIcon("inte", this.CalculateInterruptionColumn());
            if (updateTask)
            { 
                (this.Tag as Task).AddAct(ActType.AddInteInte, DateTime.Now);
            }
        }
        public void AddExte(Boolean updateTask = true)
        {
            this.AddIcon("exte", this.CalculateInterruptionColumn());
            if (updateTask)
            {
                (this.Tag as Task).AddAct(ActType.AddExteInte, DateTime.Now);
            }
        }
        public void Done(Boolean updateTask = true)
        {
            //换图标
            var image = this.First<Image>();
            image.Width = image.Height = 30;
            image.Stretch = Stretch.UniformToFill;
            image.Source = new BitmapImage(new Uri(Path.Combine(Config.AppPath, "Images/tick.png")));
            image.Tag = "done";
            image.Visibility = System.Windows.Visibility.Visible;
            //画线
            var textBox = this.First<UCTextBox>();
            textBox.Strikethrough();

            if (updateTask)
            { 
                (this.Tag as Task).Done = true;
                (this.Tag as Task).AddAct(ActType.MarkTaskAsDone, DateTime.Now);
            }
        }

        public void DelEsti(Boolean updateTask = true)
        {
            if (this.DelIcon("esti"))
            { 
                if (updateTask)
                {
                    (this.Tag as Task).AddAct(ActType.DelEstiPomo, DateTime.Now);
                }
            }
        }
        public void DelPomo(Boolean updateTask = true)
        {
            if (this.DelIcon("pomo"))
            { 
                if (updateTask)
                {
                    (this.Tag as Task).AddAct(ActType.DelPomo, DateTime.Now);
                }
            }
        }
        public void DelAban(Boolean updateTask = true)
        {
            if (this.DelIcon("pomoaban"))
            { 
                if (updateTask)
                {
                    (this.Tag as Task).AddAct(ActType.DelAbanPomo, DateTime.Now);
                }
            }
        }
        public void DelInte(Boolean updateTask = true)
        {
            if (this.DelIcon("inte"))
            { 
                if (updateTask)
                {
                    (this.Tag as Task).AddAct(ActType.DelInteInte, DateTime.Now);
                }
            }
        }
        public void DelExte(Boolean updateTask = true)
        {
            if (this.DelIcon("exte"))
            { 
                if (updateTask)
                {
                    (this.Tag as Task).AddAct(ActType.DelExteInte, DateTime.Now);
                }
            }
        }
        public void UnDone(Boolean updateTask = true)
        {
            this.First<Image>().Source = new BitmapImage(new Uri(Path.Combine(Config.AppPath, "Images/pencil.png")));
            this.First<Image>().Tag = "";
            this.First<UCTextBox>().TextDecorations.Clear();
            this.First<UCTextBox>().Foreground = Brushes.Black;
            this.First<Image>().Visibility = this.First<UCTextBox>().IsFocused? Visibility.Visible:Visibility.Hidden;

            if (updateTask)
            {
                (this.Tag as Task).Done = false;
                (this.Tag as Task).AddAct(ActType.MarkTaskAsUnDone, DateTime.Now);
                (Application.Current.MainWindow as MainWindow).SyncBackToNote(this.Tag as Task);
            }
        }

        public Task ToTask(Boolean isUnplannedAndUrgent = false)
        {
            Task task = this.Tag as Task;
            if (task == null)
            {
                throw new ArgumentNullException("ToTask can't be null");
            }
            task.Title = this.First<UCTextBox>().Text;
            task.Done = Convert.ToString(this.First<Image>().Tag).Equals("done");
            task.IsUnplannedAndUrgent = isUnplannedAndUrgent;
            return task;
        }

        #endregion

        #region [ Private Helpers ]

        Int32 CalculateColumn(String iconName)
        {
            iconName = iconName.Substring(0, 4);
            Int32 maxElIndex = -1;

            Grid grid = this.First<Grid>();
            UIElementCollection UIElements = grid.Children;
            Image icon;
            foreach (UIElement el in UIElements)
            {
                icon = el as Image;
                if (icon != null && icon.Tag.ToString().StartsWith(iconName))
                {
                    maxElIndex = Grid.GetColumn(el);
                }
            }
            return maxElIndex + 1;
        }
        Int32 CalculateInterruptionColumn()
        {
            UIElementCollection UIElements = this.First<Grid>().Children;
            Int32 minEstiIndex = -1, maxPomoIndex = -1;
            Image icon;
            foreach (UIElement el in UIElements)
            {
                icon = el as Image;
                if (icon != null)
                {
                    if (icon.Tag.ToString().Equals("esti"))
                    {
                        if (minEstiIndex == -1)
                        {
                            minEstiIndex = Grid.GetColumn(el);
                        }
                    }
                    if (icon.Tag.ToString().StartsWith("pomo"))
                    {
                        maxPomoIndex = Grid.GetColumn(el);
                    }
                }
            }
            if (minEstiIndex == -1)
                minEstiIndex = 0;
            if (maxPomoIndex > -1)
                maxPomoIndex++;
            return Math.Max(minEstiIndex, maxPomoIndex);
        }

        void AddIcon(String iconName, Int32 column)
        {
            Image icon = UIHelper.GetIcon(iconName);
            icon.Opacity = .7;
            this.First<Grid>().Children.Add(icon);
            Grid.SetRow(icon, 0);
            Grid.SetColumn(icon, column);
        }

        Boolean DelIcon(String iconName)
        {
            var icons = this.First<Grid>().FindAll<Image>();
            if (icons.Count > 0)
            {
                this.First<Grid>().Children.Remove( 
                    icons.FindLast((image) => {
                        return image.Tag.Equals(iconName);
                    })
                );
                return true;
            }
            return false;
        }

        #endregion

        #region [ ContextMenu ]

        private void BtnCancelTask_Click(object sender, RoutedEventArgs e)
        {
            if ((this.Tag as Task).Done)
            {
                return;
            }
            var task = (this.Tag as Task);
            task.AddAct(ActType.CancelTask,DateTime.Now);

            (Application.Current.MainWindow as MainWindow).SyncBackToNote(task);

            this.First<Image>().Source = new BitmapImage(new Uri(Path.Combine(Config.AppPath, "Images/pencil.png")));
            this.First<Image>().Tag = "";
            this.First<UCTextBox>().Text = "";
            this.First<Grid>().Children.Clear();

            task = new Task(task.Id);
            this.Tag = task;
        }

        private void BtnDelEsti_Click(object sender, RoutedEventArgs e)
        {
            DelEsti();
        }

        private void BtnDelPomo_Click(object sender, RoutedEventArgs e)
        {
            DelPomo();
        }

        private void BtnDelInte_Click(object sender, RoutedEventArgs e)
        {
            DelInte();
        }

        private void BtnDelExte_Click(object sender, RoutedEventArgs e)
        {
            DelExte();
        }

        private void BtnDelDone_Click(object sender, RoutedEventArgs e)
        {
            UnDone();
        }

        private void BtnSinaWeibo_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://weibo.com/cotime");  
        }

        private void BtnImproveAdvice_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://cotime.codeplex.com/workitem/list/basic");
        }

        private void BtnDenote_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://cotime.codeplex.com/documentation");
        }

        private void ContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {

        }

        #endregion
    }
}
